package com.rlyy.rsj.job;

import com.rlyy.aibase.utils.base.TableNode;
import com.rlyy.rsj.dao.BaseDao;
import com.rlyy.rsj.dao.OrgDao;
import com.rlyy.rsj.dao.OrgpDao;
import com.rlyy.rsj.service.BilService;
import com.rlyy.rsj.utils.DistributeLock;
import com.rlyy.rsj.utils.RedisKeyFactory;
import com.rlyy.rsj.utils.RedisUtils;
import common.util.DateTimeFormatterUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import static com.rlyy.rsj.utils.DistributeLock.OneAndHalfMun;


/**
 * 下月凌晨一点，生成上月账单
 * 错误日志 [DoUpBilJob.ERROR] 开头
 */
@Component
public class DoUpBilJob implements IScheduler {

    private static final Logger logger = LoggerFactory.getLogger(DoUpBilJob.class);
    private static final BilService bilService = BilService.getInstance();
    private static final OrgpDao orgpDao = OrgpDao.getInstance();
    private static final OrgDao orgDao = OrgDao.getInstance();

    private static final String LOCK_KEY = RedisKeyFactory.wrapJobKey(DoUpBilJob.class.getName());
    private static final String BILL_KEY = RedisKeyFactory.wrapJobKey("bill");
    private static final String HEALTH_KEY = RedisKeyFactory.wrapJobKey("bill_health");
    @Override
    @Scheduled(cron = "0 */1 * * * ?")
    public void scheduler() {
        boolean lock = DistributeLock.lock(LOCK_KEY, "1", OneAndHalfMun);
        if(lock) {
            logger.info("{}-执行DoUpBilJob!",LOCAL_INFO);

            TableNode tableNode = orgDao.getOrgIdsAll();
            if(tableNode == null || null == tableNode.toList() || tableNode.toList().size() == 0){
                logger.warn("[DoUpBilJob.ERROR] {}-没有获取到当前的机构ID列表！执行日期::" + new SimpleDateFormat("yyyy-MM-dd"),LOCAL_INFO);
            }

            List<Map<String,Object>> table = tableNode.toList();

            BaseDao.invokeSql(conn -> {

                for(Map<String,Object> node : table){
                    if(node == null || node.size() == 0){
                        continue;
                    }
                    String orgId = (String) node.get("Org_Id");

                    if(StringUtils.isBlank(orgId)){
                        continue;
                    }

                    try {
                        insertPreMonthBil(orgId, conn);
                    } catch (Exception e) {
                        logger.error("[DoUpBilJob.ERROR] "+LOCAL_INFO+"-执行当前机构ID账单生成失败！\t" + orgId, e);
                    }
                }

                // 修改当前所有机构，所有账单  剩余量
                try {
                    bilService.updateCure(conn);
                } catch (SQLException e) {
                    logger.error("[DoUpBilJob.ERROR] "+LOCAL_INFO+"-执行更新当月失败！");
                }
                RedisUtils.set(BILL_KEY, DateTimeFormatterUtil.dateTimeToString(LocalDateTime.now()), -1);
                DistributeLock.unlock(LOCK_KEY);
                return null;
            });
        } else {
            logger.warn("{}-DoUpBilJob未执行！",LOCAL_INFO);
        }
        //统计存活状态
        RedisUtils.hset(HEALTH_KEY, LOCAL_INFO, DateTimeFormatterUtil.dateTimeToString(LocalDateTime.now()));
    }

    private void insertPreMonthBil(String orgId, Connection conn) throws Exception {
        TableNode tableNode = orgpDao.getBillInfoByOrgId(orgId, conn);
        List<Map<String, Object>> data = tableNode.toList();
        if(data.size() == 0){
            logger.warn("{}-当前机构目前还没有使用中的合同:::" + orgId,LOCAL_INFO);
            return;
        }

        for(Map<String, Object> map : data){
            if(map.size() == 0){
                continue;
            }
            int i = bilService.insertBilCurMonth(orgId, map);
            if(i == 0){
                logger.error("[DoUpBilJob.ERROR]:::机构ID:{}:::合同ID:{}账单生成失败::" , orgId, map.get("orgp_id"));
            }
        }
    }

}
